﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Speakup
{
    public static class Week
    {
        static public readonly DateTime KnownDate = new DateTime(2010, 4, 26);
        static public readonly int KnownWeek = 9;

        private static DateTime MoveToMonday(DateTime date)
        {
            if (date.DayOfWeek == DayOfWeek.Monday) return date;
            
            int curDay = (int)date.DayOfWeek;
            if(curDay == 0) curDay = 7;

            int deltaDays = curDay - (int)DayOfWeek.Monday;
            return date - TimeSpan.FromDays(deltaDays);
        }

        private static DateTime MoveToSunday(DateTime date)
        {
            if (date.DayOfWeek == DayOfWeek.Sunday) return date;

            int curDay = (int)date.DayOfWeek;
            if (curDay == 0) curDay = 7;

            int deltaDays = 7 - curDay;
            return date + TimeSpan.FromDays(deltaDays);
        }

        public static int GetWeek( DateTime requestDate)
        {
            return GetWeek(KnownDate, KnownWeek, requestDate);
        }

        public static int GetWeek(DateTime knownDate, int knownWeek, DateTime requestDate)
        {
            if( knownDate < requestDate)
            {
                knownDate = MoveToMonday(knownDate);
                requestDate = MoveToMonday(requestDate);
            }
            else
            {
                knownDate = MoveToSunday(knownDate);
                requestDate = MoveToSunday(requestDate);
            }

            int deltaDays = (int)(requestDate - knownDate).TotalDays;
            int deltaWeeks = deltaDays / 7;

            int week = (knownWeek + deltaWeeks) % 12;

            if(week < 0)  week+=12;
            if(week == 0) week = 12;

            return week;
        }

        static private DateTime sm_currentKnownDate = KnownDate;
        static public DateTime CurrentKnownDate
        {
            get
            {
                return sm_currentKnownDate;
            }
            set
            {
                int preCurWeek = CurrentWeek;

                sm_currentKnownDate = value;

                int postCurWeek = CurrentWeek;

                if (preCurWeek != postCurWeek)
                {
                    OnCurrentWeekChanged();
                }
            }
        }

        static private int sm_currentKnownWeek = KnownWeek;
        static public int CurrentKnownWeek
        {
            get
            {
                return sm_currentKnownWeek;
            }
            set
            {
                int preCurWeek = CurrentWeek;

                sm_currentKnownWeek = value;

                int postCurWeek = CurrentWeek;

                if (preCurWeek != postCurWeek)
                {
                    OnCurrentWeekChanged();
                }
            }
        }

        static public int CurrentWeek 
        {
            get
            {
                return GetWeek(KnownDate, KnownWeek, DateTime.Now);
            }
            set
            {
                int preCurWeek = CurrentWeek;

                sm_currentKnownWeek = value;
                sm_currentKnownDate = DateTime.Today;

                int postCurWeek = CurrentWeek;

                if (preCurWeek != postCurWeek)
                {
                    OnCurrentWeekChanged();
                }
            }
        }

        static public event EventHandler<EventArgs> CurrentWeekChanged;
        static private void OnCurrentWeekChanged()
        {
            EventHandler<EventArgs> _event = CurrentWeekChanged;
            if (_event != null)
            {
                _event(null, null);
            }        
        }
    }
}
